home *** CD-ROM | disk | FTP | other *** search
- From: ihnp4!amdcad!idi!bene!luke!steven
- Subject: cpg revisited
- Reply-To: steven@luke.UUCP (Steven List)
- Newsgroups: mod.sources
- Approved: john@genrad.UUCP
-
- Mod.sources: Volume 2, Issue 1
- Submitted by: steven@luke.UUCP (Steven List)
-
-
- This is a reposting of my C source listing formatter, `cpg'. The main
- reason for the reposting is that someone actually asked for another
- command line option. The addition is a `-b' option, which causes the
- use of only the basename portion of the file name in page headers.
-
- I also included a little conditional preprocessor stuff for those pieces
- that I know (believe) are version dependent. So, if you -DBSD, strchr
- and strrchr become index and rindex. If anybody finds anything else
- that is version dependent (and if they have the fix), please send it to
- me.
-
- I found that the changes involved enough of the source file that posting
- a patch would have been almost as large as reposting. So here are the
- manual page and source updated.
-
- Thanks to Bill Turner (hpdsd!hppsd2!bill) for the suggestion (he got an
- early copy of this article for his efforts).
-
- ***
- * Steven List @ Benetics Corporation, Mt. View, CA
- * {cdp,greipa,idi,oliveb,sun,tolerant}!bene!luke!steven
- ***
- --------------------------- Cut Here -----------------------------------
- #! /bin/sh
- # This is a shell archive, meaning:
- # 1. Remove everything above the #! /bin/sh line.
- # 2. Save the resulting text in a file.
- # 3. Execute the file with /bin/sh (not csh) to create the files:
- # cpg.1
- # cpg.c
- # This archive created: Mon Jun 24 20:19:05 1985
- export PATH; PATH=/bin:$PATH
- echo shar: extracting "'cpg.1'" '(5283 characters)'
- if test -f 'cpg.1'
- then
- echo shar: will not over-write existing file "'cpg.1'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'cpg.1'
- X.so /b/doc/nroffmacros/manmac
- X.TH "cpg" "1" "Benetics Local"
- X.ds C \fIcpg\fR
- X.tr ~
- X.fi
- X.ad b
- X.SH NAME
- Xcpg - C source listing formatter
- X.SH SYNOPSIS
- Xcpg [ -b<asename> ] [ -t tabstop ] [ file... ]
- X.SH DESCRIPTION
- X\*C is a C language source listing formatter. It employs certain
- Xtriggers to perform its formatting. Those same triggers may be used to
- Xextract in-line documentation to create documentation. At the end of
- Xthe listing produced by \*C is a table of contents of all files and
- Xfunctions contained in the current listing. The table of contents is
- Xsorted alphabetically by function and file.
- X.P
- XThe listing produced by \*C includes on each line a line number. On each
- Xline containing any braces ({}), there will also be a
- Xnesting level indicator. The nesting level indicator includes a number
- X(the current nesting level) and a directional character. The
- Xdirectional characters are:
- X.IP > 6
- XThe nesting level increased on this line
- X.IP < 6
- XThe nesting level decreased on this line
- X.IP * 6
- XThe nesting level changed both ways, with a net change of zero
- X.P
- XThe triggers that \*C recognizes are itemized below. Each must appear
- Xin column 1.
- X.TP
- X<formfeed>
- XA formfeed will cause a new page to be started with a full header.
- X.TP
- X/*F filename *<anything>
- XThe file name may be specified in a comment preceding a descriptive
- Xheader block. The filename argument must be delimited by asterisks in
- Xthe trigger. The filename will appear in all page headings up to the
- Xnext filename trigger or the next file. A filename comment block
- X\fBmust\fR be terminated by the endofblock trigger (see below).
- XThis trigger will print as a line in the listing. This trigger causes
- Xthe start of a new page (form feed) in the listing, with printing of the
- Xpage header including the current file name.
- X.TP
- X/*H funcname *<anything>
- XThe function name may be specified in a comment preceding a descriptive
- Xheader block. The funcname argument must be delimited by asterisks in
- Xthe trigger. The funcname will appear in all page headings up to the
- Xnext funcname trigger or the next file. A funcname comment block
- X\fBmust\fR be terminated by the endofblock trigger (see below).
- XThis trigger will print as a line in the listing. This trigger causes
- Xthe start of a new page (form feed) in the listing, with printing of the
- Xpage header including the current function name.
- X.TP
- X/*E*/
- XThis is the endofblock trigger. Everything between the last filename or
- Xfuncname trigger and the endofblock trigger will be passed straight
- Xthrough by \*C without evaluation of nesting levels, comments, or quoted
- Xstrings. Thus, a header block is treated as one long comment by \*C.
- XThis trigger will print as a line in the listing.
- X.TP
- X/*P*/
- XThis is a page eject trigger. It will not print in the listing, but
- Xwill be counted for line numbering purposes. This trigger causes the
- Xpage heading, title, and subtitle to be reprinted based on their current
- Xvalues (see title and subtitle below).
- X.TP
- X/*S <text> */
- XThis is the subtitle trigger. It determines the contents of the second
- Xtitle line on the page header. All characters after the initial space
- Xand up to but not including the following asterisk (required) are
- Xincluded as part of the subtitle. This trigger will not print in the
- Xlisting but will be counted for line numbering purposes.
- X.TP
- X/*T <text> */
- XThis is the title trigger. It determines the contents of the first
- Xtitle line on the page header. All characters after the initial space
- Xand up to but not including the following asterisk (required) are
- Xincluded as part of the title. This trigger will not print in the
- Xlisting but will be counted for line numbering purposes.
- X.SS Options
- X.IP "-b" 16
- XThe basename option causes \fIcpg\fR to use only the basename portion of
- Xthe filename (whether obtained from the fileheader trigger or the
- Xcurrent filename) in page headers as well as the table of contents.
- XThus, if a file is printed using "cpg -bt4 `pwd`/xyz.c", only "xyz.c"
- Xwill show up in the page header.
- X.IP "-t tabstop" 16
- XThe tabstop argument to the -t option specifies how to expand tabs. The
- Xexpansion is performed automatically with a tabstop of 8 if none is
- Xspecified.
- X.SS Arguments
- X.IP file 16
- XAny number of file names may be specified on the command line (within
- Xlimits set by whichever shell is used). Each file will be formatted and
- Xits name added to the table of contents. If no file names are
- Xspecified, \*C will read the standard input.
- X.SH FILES
- X.IP "/tmp/toc_XXXXXX" 20
- Xtemporary file for building the table of contents.
- X.SH "SEE ALSO"
- Xdtab(1), nl(1), pr(1), sort(1)
- X.SH NOTES
- XThis tool was developed at Benetics Corporation.
- X.P
- XA side note: \*C also properly processes comments in shell scripts and
- Xmakefiles. These comments are correctly handled when the comment
- Xcharacter (# or :) is the first nonblank character on a line. In order
- Xto facilitate documentation of shell scripts, \*C recognizes the
- Xsequences #{ and #} as the beginning and ending of nesting, and treats
- Xthem as it does in C program sources. Thus lengthy for, if, while, and
- Xcase statements may be more clearly documented as to nesting levels,
- Xparticulary in shell scripts.
- X.SH AUTHOR
- X.na
- X.nf
- XSteven M. List
- XBenetics Corporation
- XMountain View, CA.
- X{cdp,idi,greipa,oliveb,sun,tolerant}!bene!luke!steven
- SHAR_EOF
- if test 5283 -ne "`wc -c < 'cpg.1'`"
- then
- echo shar: error transmitting "'cpg.1'" '(should have been 5283 characters)'
- fi
- fi # end of overwriting check
- echo shar: extracting "'cpg.c'" '(24738 characters)'
- if test -f 'cpg.c'
- then
- echo shar: will not over-write existing file "'cpg.c'"
- else
- sed 's/^ X//' << \SHAR_EOF > 'cpg.c'
- X/*Tcpg - c program source listing formatter */
- X/*F cpg.c **********************************************************
- X *
- X * cpg.c
- X *
- X * DESCRIPTION OF FILE CONTENTS:
- X * C source program listing formatter source.
- X *
- X * Cpg provides the facility to print out a C language source file
- X * with headers, nesting level indicators, and table of contents.
- X * It makes use of "triggers" for page headings, titles and
- X * subtitles, and pagination. It also recognizes function
- X * declarations and form feeds and treats them appropriately.
- X *
- X *******************************************************************/
- X/*E*/
- X/*S includes, defines, and globals */
- X/*P*/
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <time.h>
- X
- X#define EQ ==
- X#define NE !=
- X#define GT >
- X#define GE >=
- X#define LT <
- X#define LE <=
- X#define OR ||
- X#define AND &&
- X
- X#define TRUE 1
- X#define FALSE 0
- X#define YES 1
- X#define NO 0
- X
- X#define SPACE ' '
- X#define NUL '\0'
- X
- Xtypedef short BOOL;
- X
- X#define INULL -32768
- X#define LNULL -2147483648
- X
- X#define MAX(a,b) ((a) > (b) ? (a) : (b))
- X#define MIN(a,b) ((a) < (b) ? (a) : (b))
- X#define ABS(a) ((a) >= 0 ? (a) : -(a))
- X
- X#define LINESINHEAD 6
- X#define LPP 60
- X#define MAXWIDTH 130
- X
- X#define notend(ll) ((ll[0] EQ SLASH AND ll[1] EQ STAR AND ll[2] EQ 'E') ? FALSE : TRUE)
- X#define SLASH '/'
- X#define STAR '*'
- X#define DQUOTE '"'
- X#define SQUOTE '\''
- X#define BSLASH '\\'
- X
- X#ifdef BSD
- X#define strrchr rindex
- X#define strchr index
- X#endif BSD
- X
- Xextern char *strrchr ();
- Xextern char *strchr ();
- X
- Xchar *basename ();
- X
- Xchar tim_lin[40];
- Xchar *file_name;
- Xchar fh_name[50] = "";
- Xchar fnc_name[40] = "";
- Xchar subttl[70] = "";
- Xchar title[70] = "";
- Xchar tocname[] = "/tmp/toc_XXXXXX";
- X
- Xint nlvl = 0;
- X
- Xint page_line = LPP+1;
- Xint pageno = 1;
- X
- Xint tabstop = 8;
- X
- Xint infunc = FALSE;
- Xint logging = 0;
- Xint BASENAME = FALSE;
- X
- Xint incomment = FALSE;
- Xint insquote = FALSE;
- Xint indquote = FALSE;
- X
- Xchar specline = FALSE;
- X
- XFILE *tocfile;
- XFILE *fd;
- X
- Xchar *pgm;
- X
- Xchar *ReservedWord[] = {
- X "auto", "bool", "break", "case", "char", "continue",
- X "default", "do", "double", "else", "entry", "enum",
- X "extern", "float", "for", "goto", "if",
- X "int", "long", "register", "return", "short",
- X "sizeof", "static", "struct", "switch",
- X "typedef", "union", "unsigned", "void", "while",
- X NULL };
- X
- X/*S main function */
- X/*Hmain */
- X/*E*/
- X
- Xmain (ac, av)
- Xint ac;
- Xchar **av;
- X{
- X char *std_input = "standard input"; /* input file name */
- X
- X long cur_time; /* place for current raw time */
- X
- X long *time(); /* return raw time from system */
- X
- X register int i; /* temporary for indexes, etc. */
- X
- X struct tm *tim; /* return from localtime */
- X struct tm *localtime ();
- X
- X char cmdbuf[40]; /* place to format sort command */
- X
- X extern char *optarg; /* option argument pointer */
- X extern int optind; /* option index */
- X
- X pgm = basename (av[0]);
- X
- X while ((i = getopt (ac, av, "bl:t:")) NE EOF)
- X {
- X switch (i)
- X {
- X case 'b':
- X BASENAME = TRUE;
- X break;
- X case 'l':
- X logging = atoi (optarg);
- X break;
- X case 't':
- X tabstop = atoi (optarg);
- X break;
- X default:
- X fprintf (stderr,
- X "usage: %s [ -b<asename> ] [ -t <tabstop> ] [ files... ]\n",
- X pgm);
- X }
- X }
- X
- X /* ------------------------------------------------------------ */
- X /* set up the date/time portion of page headings */
- X /* ------------------------------------------------------------ */
- X
- X time(&cur_time);
- X
- X tim = localtime (&cur_time);
- X sprintf (tim_lin, "Printed: %02d/%02d/%02d at %2d:%02d %s",
- X tim->tm_mon + 1, tim->tm_mday, tim->tm_year,
- X tim->tm_hour GT 12 ? tim->tm_hour - 12 : tim->tm_hour,
- X tim->tm_min,
- X tim->tm_hour GE 12 ? "PM" : "AM" );
- X
- X /* ------------------------------------------------------------ */
- X /* create the temporary file for the table of contents */
- X /* don't bother if output is to a terminal */
- X /* ------------------------------------------------------------ */
- X
- X mktemp (tocname);
- X if (!isatty (1))
- X {
- X tocfile = fopen (tocname, "w");
- X if (!tocfile)
- X {
- X fprintf (stderr, "%s: unable to create tocfile %s\n",
- X pgm, tocname);
- X exit (2);
- X }
- X }
- X
- X /* ------------------------------------------------------------ */
- X /* if no file names, read standard input */
- X /* ------------------------------------------------------------ */
- X
- X if (optind EQ ac)
- X {
- X fd = stdin;
- X file_name = std_input;
- X dofile (fd);
- X }
- X else
- X {
- X /* ------------------------------------------------------------ */
- X /* process each file named on the command line */
- X /* ------------------------------------------------------------ */
- X
- X for (i = optind; i LT ac; i++)
- X {
- X /* ------------------------------------------------------------ */
- X /* special file name `-' is standard input */
- X /* ------------------------------------------------------------ */
- X
- X if (strcmp (av[i], "-") EQ 0)
- X {
- X fd = stdin;
- X file_name = std_input;
- X }
- X else
- X {
- X fd = fopen (av[i], "r");
- X if (fd EQ NULL)
- X {
- X fprintf (stderr,
- X "cpg: unable to open %s\n", av[i]);
- X }
- X }
- X if (fd NE NULL)
- X {
- X if (BASENAME) strcpy (fh_name, basename (av[i]));
- X else strcpy (fh_name, av[i]);
- X file_name = av[i];
- X dofile (fd);
- X fclose (fd);
- X }
- X }
- X }
- X
- X fflush (stdout);
- X
- X /* ------------------------------------------------------------ */
- X /* sort and print the table of contents - straight alpha order */
- X /* on function and file name */
- X /* ------------------------------------------------------------ */
- X
- X if (!isatty (1))
- X {
- X fclose (tocfile);
- X sprintf (cmdbuf, "sort +1 -2 +0 -1 -u -o %s %s", tocname, tocname);
- X system (cmdbuf);
- X tocfile = fopen (tocname, "r");
- X if (!tocfile)
- X {
- X fprintf (stderr, "%s: unable to read tocfile\n", pgm);
- X exit (2);
- X }
- X else
- X {
- X tocout (tocfile);
- X fclose (tocfile);
- X if (!logging) unlink (tocname);
- X }
- X }
- X
- X fprintf (stdout, "\f");
- X
- X exit (0);
- X}
- X/*Sdofile - process an input file */
- X/*Hdofile*/
- X/*E*/
- Xdofile (fd)
- XFILE *fd;
- X{
- X register int i; /* temporary */
- X
- X int lineno = 1; /* line number in current file */
- X
- X register char *line; /* current line pointer */
- X
- X char ibuf[MAXWIDTH]; /* original input line */
- X char ebuf[MAXWIDTH]; /* line with tabs expanded */
- X
- X register char *p; /* temporary char pointer */
- X
- X /* ------------------------------------------------------------ */
- X /* initialize the function name to `.' - unknown */
- X /* retrieve the basename portion of the file name */
- X /* ------------------------------------------------------------ */
- X
- X strcpy (fnc_name, ".");
- X
- X /* ------------------------------------------------------------ */
- X /* if building TOC, add this entry */
- X /* ------------------------------------------------------------ */
- X
- X if (!isatty (1))
- X fprintf (tocfile,
- X "%s %s %d %d\n", fh_name, fnc_name, pageno, lineno);
- X
- X /* ------------------------------------------------------------ */
- X /* if tabs are to be expanded, use the expansion buffer */
- X /* ------------------------------------------------------------ */
- X
- X if (tabstop) line = ebuf;
- X else line = ibuf;
- X
- X /* ------------------------------------------------------------ */
- X /* process each line in the file, looking for triggers */
- X /* ------------------------------------------------------------ */
- X
- X while (fgets (ibuf, MAXWIDTH, fd) NE NULL)
- X {
- X if (logging GE 9) fprintf (stderr, "%s: LOG: %s", pgm, line);
- X /* ------------------------------------------------------------ */
- X /* expand the input line */
- X /* ------------------------------------------------------------ */
- X
- X expand (ebuf, ibuf);
- X
- X if (line[0] EQ SLASH AND line[1] EQ STAR)
- X {
- X /* ------------------------------------------------------------ */
- X /* comment found - could be a trigger */
- X /* ------------------------------------------------------------ */
- X
- X switch (line[2])
- X {
- X case 'F':
- X case 'H':
- X {
- X if (logging GE 9) fprintf (stderr, "F/H header\n");
- X header (&lineno, line, fd);
- X break;
- X }
- X case 'P':
- X {
- X if (logging GE 9) fprintf (stderr, "page break\n");
- X print_head ();
- X lineno++;
- X break;
- X }
- X case 'S':
- X {
- X if (logging GE 9) fprintf (stderr, "subtitle\n");
- X getname (line, subttl);
- X lineno++;
- X break;
- X }
- X case 'T':
- X {
- X if (logging GE 9) fprintf (stderr, "title\n");
- X getname (line, title);
- X /* print_head (); */
- X lineno++;
- X break;
- X }
- X default:
- X {
- X if (logging GE 9) fprintf (stderr, "other comment\n");
- X print (&lineno, line);
- X break;
- X }
- X }
- X }
- X else
- X {
- X /* ------------------------------------------------------------ */
- X /* not a comment - check for function declaration */
- X /* if a form feed is found, start a new page with header */
- X /* ------------------------------------------------------------ */
- X
- X if (logging GE 9) fprintf (stderr, "not a comment\n");
- X if (!nlvl AND !isatty (1)) infunc = ckfunc (lineno, line);
- X if (*line EQ '\f') print_head ();
- X else print (&lineno, line);
- X }
- X }
- X
- X page_line = LPP+1; /* force new page after file */
- X title[0] = NUL; /* clear title and subtitle */
- X subttl[0] = NUL;
- X
- X return;
- X}
- X/*Sheader - construct and print header box */
- X/*Hheader*/
- X/*E*/
- Xheader (lineno, line, fd)
- Xregister int *lineno;
- Xregister char *line;
- Xregister FILE *fd;
- X{
- X register char *p;
- X
- X if (line[2] EQ 'F')
- X {
- X getname (line, fh_name);
- X if (BASENAME) strcpy (fh_name, basename (fh_name));
- X strcpy (fnc_name, ".");
- X }
- X else if (line[2] EQ 'H')
- X {
- X getname (line, fnc_name);
- X }
- X
- X if (!isatty (1))
- X fprintf (tocfile,
- X "%s %s %d %d\n", fh_name, fnc_name, pageno, *lineno);
- X
- X print_head ();
- X
- X print (lineno, line);
- X
- X while (fgets (line, MAXWIDTH, fd) NE NULL AND
- X notend (line))
- X {
- X if (line[0] EQ SLASH AND line[1] EQ STAR AND line[2] EQ 'P')
- X {
- X print_head ();
- X (*lineno)++;
- X }
- X else
- X {
- X print (lineno, line);
- X }
- X }
- X
- X print (lineno, line);
- X
- X return;
- X}
- X/*Sgetname - get a string from a signal line */
- X/*Hgetname */
- X/*E*/
- Xgetname (line, name)
- Xregister char *line;
- Xregister char *name;
- X{
- X register int i;
- X register int j;
- X
- X /* ------------------------------------------------------------ */
- X /* skip leading spaces in the trigger line */
- X /* copy up to trailing asterisk or end-of-line */
- X /* strip trailing spaces */
- X /* ------------------------------------------------------------ */
- X
- X for (i = 3; isspace(line[i]) AND i LT MAXWIDTH; i++);
- X
- X for (j = 0; line[i] AND line[i] NE '*'; i++, j++)
- X {
- X name[j] = line[i];
- X }
- X
- X while (j-- GT 0 AND isspace (name[j]));
- X
- X name[++j] = NUL;
- X
- X return;
- X}
- X/*Sprint - print a line with line number */
- X/*Hprint */
- X/*E*/
- Xprint (lineno, line)
- Xregister int *lineno;
- Xregister char *line;
- X{
- X register int llen = strlen (line);
- X register int i;
- X
- X register char sc = specline ? '*' : ' ';
- X
- X int j = 0;
- X
- X register char dc = NUL;
- X
- X /* ------------------------------------------------------------ */
- X /* new page with header if page length is exceeded */
- X /* ------------------------------------------------------------ */
- X
- X if (page_line GT LPP)
- X {
- X print_head ();
- X }
- X
- X /* ------------------------------------------------------------ */
- X /* if brace(s) found, */
- X /* modify the nesting level by the net nesting delta */
- X /* select the indicator according to the net delta */
- X /* if nexting is back to zero (none), clear function name */
- X /* ------------------------------------------------------------ */
- X
- X if (fnd (line, &j))
- X {
- X nlvl += j;
- X
- X if (j LT 0) dc = '<';
- X else if (j EQ 0) dc = '*';
- X else dc = '>';
- X
- X i = nlvl;
- X if (j LT 0) i++;
- X fprintf (stdout, "%4d%c%2d%c ",
- X (*lineno)++, sc, i, dc);
- X if (nlvl EQ 0) strcpy (fnc_name, ".");
- X }
- X else
- X {
- X fprintf (stdout, "%4d%c ", (*lineno)++, sc);
- X }
- X
- X /* ------------------------------------------------------------ */
- X /* break up long lines by finding the first space form the end */
- X /* ------------------------------------------------------------ */
- X
- X if (llen GT 71)
- X {
- X for (i = 70; i GE 0; i--)
- X {
- X if (line[i] EQ SPACE)
- X {
- X fprintf (stdout, "%*.*s \\\n", i, i, line);
- X page_line++;
- X break;
- X }
- X }
- X
- X j = 79 - (llen - i);
- X
- X for (j; j GE 0; j--) putc (SPACE, stdout);
- X
- X fprintf (stdout, "%s", &line[i+1]);
- X }
- X else
- X {
- X fprintf (stdout, "%s", line);
- X }
- X
- X page_line++;
- X
- X specline = FALSE; /* true if function declaration */
- X
- X return;
- X}
- X/*Sprint_head - print the page heading with page number */
- X/*Hprint_head */
- X/*E*/
- Xprint_head ()
- X{
- X char headbuf[80];
- X register int len;
- X
- X sprintf (headbuf, "[ %s | %s <- %s",
- X tim_lin, fh_name, fnc_name);
- X
- X for (len = strlen (headbuf); len LT 68; len++) headbuf[len] = SPACE;
- X
- X sprintf (&headbuf[68], "Page %-4d ]", pageno++);
- X fprintf (stdout, "\f\n");
- X if (!isatty (1))
- X fprintf (stdout, "_______________________________________\
- X________________________________________");
- X fprintf (stdout, "\n%s\n", headbuf);
- X fprintf (stdout, "[-------------------------------+------\
- X---------------------------------------]\n");
- X
- X if (*title)
- X {
- X sprintf (headbuf, "[ %s", title);
- X }
- X else
- X {
- X sprintf (headbuf, "[ %s", fh_name);
- X }
- X for (len = strlen (headbuf); len LT 78; len++) headbuf[len] = SPACE;
- X headbuf[78] = ']';
- X fprintf (stdout, "%s\n", headbuf);
- X
- X if (*subttl)
- X {
- X sprintf (headbuf, "[ %s", subttl);
- X }
- X else
- X {
- X sprintf (headbuf, "[ %s", fnc_name);
- X }
- X for (len = strlen (headbuf); len LT 78; len++) headbuf[len] = SPACE;
- X headbuf[78] = ']';
- X fprintf (stdout, "%s", headbuf);
- X
- X if (!isatty (1))
- X fprintf (stdout, "\r_______________________________________\
- X________________________________________");
- X fprintf (stdout, "\n\n");
- X
- X page_line = LINESINHEAD;
- X
- X return;
- X}
- X/*S fnd - return true if a brace is found */
- X/*H fnd */
- X/*E*/
- Xfnd (in, nchg)
- Xregister char *in;
- Xregister int *nchg;
- X{
- X# define LBRACE '{'
- X# define RBRACE '}'
- X# define SHARP '#'
- X# define COLON ':'
- X
- X register found = FALSE; /* true if keyword found */
- X
- X register char blank = TRUE; /* used to check for shell/make */
- X /* comments beginning with #/: */
- X register int inshcomment = FALSE; /* true if in shell comment */
- X
- X *nchg = 0; /* initialize net change to zero */
- X
- X /* ------------------------------------------------------------ */
- X /* check each character of the line */
- X /* ------------------------------------------------------------ */
- X
- X for (in; *in; in++)
- X {
- X if (!incomment AND !inshcomment AND !indquote AND !insquote)
- X {
- X if (logging GE 9) fprintf (stderr, "not in comment or quote\n");
- X if (*in EQ SLASH AND *(in+1) EQ STAR)
- X {
- X incomment = TRUE;
- X blank = FALSE;
- X if (logging GE 9) fprintf (stderr, "new comment\n");
- X }
- X else if (blank AND
- X ((*in EQ SHARP OR *in EQ COLON) AND
- X (*(in+1) NE LBRACE AND *(in+1) NE RBRACE))
- X )
- X {
- X inshcomment = TRUE;
- X blank = FALSE;
- X if (logging GE 9) fprintf (stderr, "new shell comment\n");
- X }
- X else if (*in EQ DQUOTE AND
- X (*(in-1) NE BSLASH OR *(in-2) EQ BSLASH))
- X {
- X indquote = TRUE;
- X blank = FALSE;
- X if (logging GE 9) fprintf (stderr, "new dquote\n");
- X }
- X else if (*in EQ SQUOTE AND
- X (*(in-1) NE BSLASH OR *(in-2) EQ BSLASH))
- X {
- X insquote = TRUE;
- X blank = FALSE;
- X if (logging GE 9) fprintf (stderr, "new squote\n");
- X }
- X else if (*in EQ LBRACE)
- X {
- X (*nchg)++;
- X found = TRUE;
- X blank = FALSE;
- X if (logging GE 9) fprintf (stderr, "nest in\n");
- X }
- X else if (*in EQ RBRACE)
- X {
- X (*nchg)--;
- X found = TRUE;
- X blank = FALSE;
- X if (logging GE 9) fprintf (stderr, "nest out\n");
- X }
- X else if (!isspace (*in))
- X {
- X blank = FALSE;
- X }
- X }
- X else if (incomment AND *in EQ STAR AND *(in+1) EQ SLASH)
- X {
- X incomment = FALSE;
- X if (logging GE 9) fprintf (stderr, "end comment\n");
- X }
- X else if (indquote AND *in EQ DQUOTE AND
- X (*(in-1) NE BSLASH OR *(in-2) EQ BSLASH))
- X {
- X indquote = FALSE;
- X if (logging GE 9) fprintf (stderr, "end dquote\n");
- X }
- X else if (insquote AND *in EQ SQUOTE AND
- X (*(in-1) NE BSLASH OR *(in-2) EQ BSLASH))
- X {
- X insquote = FALSE;
- X if (logging GE 9) fprintf (stderr, "end squote\n");
- X }
- X }
- X
- X return found;
- X}
- X/*Stocout - print out the table of contents */
- X/*Htocout */
- X/*E*/
- Xtocout (toc)
- XFILE *toc;
- X{
- X char buf[80];
- X char filenam[80];
- X char fncnam[80];
- X int page;
- X int line;
- X
- X char outline[80];
- X
- X register int toclines = 99;
- X
- X while (fscanf (toc, "%s%s%d%d", filenam, fncnam, &page, &line) EQ 4)
- X {
- X if (toclines GT 54)
- X {
- X printf ("\f\n\
- X _____________________\n\
- X [ TABLE OF CONTENTS ]\r\
- X _____________________\n\n\
- X File -> Function Page Line\r\
- X________________________________________\
- X________________________________________\n\n");
- X toclines = 0;
- X }
- X
- X toclines++;
- X
- X printf ("\
- X %16s -> %-16.16s ............ %3d %5d\n",
- X filenam, *fncnam EQ '.' ? "START" : fncnam, page, line);
- X }
- X return;
- X}
- X/*S expand - expand tabs to tabstop */
- X/*H expand */
- X/*E*/
- Xexpand (to, from)
- Xregister char *to;
- Xregister char *from;
- X{
- X register int i;
- X register int tofill;
- X
- X# define BACKSPACE '\b'
- X# define FORMFEED '\f'
- X# define NEWLINE '\n'
- X# define RETURN '\r'
- X# define TAB '\t'
- X
- X i = 0;
- X
- X while (*from)
- X {
- X switch (*from)
- X {
- X case TAB:
- X tofill = tabstop - (i % tabstop);
- X i += tofill;
- X while (tofill--) *(to++) = SPACE;
- X break;
- X case NEWLINE:
- X case RETURN:
- X i = 0;
- X case FORMFEED:
- X *(to++) = *from;
- X break;
- X case BACKSPACE:
- X i--;
- X *(to++) = *from;
- X break;
- X default:
- X i++;
- X *(to++) = *from;
- X break;
- X }
- X
- X from++;
- X }
- X
- X *to = NUL;
- X
- X return;
- X}
- X/*S ckfunc - check line for function declaration */
- X/*H ckfunc */
- X/*E*/
- X
- X#define isidchr(c) (isalnum(c) || (c == '_'))
- X
- Xckfunc (lineno, s)
- Xregister int lineno;
- Xregister char *s;
- X{
- X register char *p;
- X register int Cnt;
- X register int i;
- X register int result;
- X register char found = FALSE;
- X
- X static char *_fnm = "ckfunc";
- X
- X char FunctionName[40];
- X
- X if (logging GE 3)
- X {
- X fprintf (stderr,
- X "%s<%s>: LOG: ckfunc called - line = %s",
- X pgm, _fnm, s);
- X }
- X
- X if(!strcmp (fnc_name, ".") AND !incomment && !indquote && !insquote)
- X {
- X found = TRUE;
- X
- X while (found)
- X {
- X found = FALSE;
- X p = FunctionName;
- X for (s; isascii (*s) && isspace (*s) && *s; s++);
- X if( *s == '*' )
- X {
- X for (++s; isascii (*s) && isspace (*s) && *s; s++);
- X }
- X
- X if ((*s == '_') || isalpha(*s))
- X {
- X while (isidchr (*s)) *p++ = *s++;
- X
- X *p = '\0';
- X
- X for (found = FALSE, i = 0;
- X !found AND ReservedWord[i]; i++)
- X {
- X if (!(result = strcmp (FunctionName, ReservedWord[i])))
- X found = TRUE;
- X
- X if (result < 0) break;
- X }
- X
- X if (logging GE 3 AND found)
- X {
- X fprintf (stderr,
- X "%s<%s>: LOG: reserved word = %s\n",
- X pgm, _fnm, FunctionName);
- X }
- X }
- X }
- X
- X if (logging GE 3)
- X {
- X fprintf (stderr,
- X "%s<%s>: LOG: last word = %s\n",
- X pgm, _fnm, FunctionName);
- X }
- X
- X for (s; isascii (*s) && isspace (*s) && *s; s++);
- X
- X if (*s EQ '(')
- X {
- X for (found = FALSE; *s AND !found; s++)
- X found = *s EQ ')';
- X
- X if (found)
- X {
- X for (; *s AND isspace (*s); s++);
- X
- X found = *s NE ';';
- X
- X if (found)
- X {
- X strcpy (fnc_name, FunctionName);
- X fprintf (tocfile,
- X "%s %s %d %d\n",
- X fh_name, fnc_name, pageno-1, lineno);
- X specline = TRUE;
- X }
- X }
- X }
- X }
- X
- X if (logging GE 3)
- X {
- X fprintf (stderr,
- X "%s<%s>: LOG: this line does%s contain a function declaration\n",
- X pgm, _fnm, found ? "" : " not");
- X }
- X
- X return found;
- X}
- X/*S basename - return the basename part of a pathname */
- X/*H basename *********************************************************
- X*
- X* basename
- X*
- X* given a (presumed) pathname, return the part after the last slash
- X*
- X*********************************************************************/
- X/*E*/
- Xchar *
- Xbasename (str)
- Xregister char *str;
- X{
- X register char *ret;
- X
- X if (ret = strrchr (str, '/')) ret++;
- X else ret = str;
- X
- X return ret;
- X}
- SHAR_EOF
- if test 24738 -ne "`wc -c < 'cpg.c'`"
- then
- echo shar: error transmitting "'cpg.c'" '(should have been 24738 characters)'
- fi
- fi # end of overwriting check
- # End of shell archive
- exit 0
-
-
-
-